package com.huzz.config;

import com.huzz.handler.CustAuthenticationEntryPoint;
import com.huzz.handler.CustLogoutSuccessHandler;
import com.huzz.filter.JwtAuthenticationFilter;
import com.huzz.properties.RsaKeyProperties;
import com.huzz.properties.TokenProperties;
import com.huzz.service.CustUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 描述
 *
 * @author Huzz
 * @create 2022-08-18 12:21
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustUserDetailsService custUserDetailsService;

    @Autowired
    private RsaKeyProperties rsaKeyProperties;

    @Autowired
    private TokenProperties tokenProperties;

    /**
     * 强散列哈希加密实现
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    public AuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(custUserDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        return daoAuthenticationProvider;
    }

    /**
     * 身份认证
     */
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuthenticationProvider());
    }

    /**
     * 权限认证
     * @param http
     * @throws Exception
     */
    public void configure(HttpSecurity http) throws Exception {
        // CSRF禁用，因为不使用session
        http.csrf().disable();
        //禁用cors保护机制
        http.cors().disable();
        //禁用session会话
        http.sessionManagement().disable();
        //禁用form表单登录
        http.formLogin().disable();
        //增加自定义认证过滤器（认证服务需要配置）
        http.addFilter(new JwtAuthenticationFilter(super.authenticationManager(), rsaKeyProperties, tokenProperties));
        // 过滤请求 对于登录login 注册register 验证码captchaImage 允许匿名访问
        http.authorizeRequests().antMatchers("/login", "/register", "/captchaImage").anonymous();
        // 除上面外的所有请求全部需要鉴权认证
        http.authorizeRequests().anyRequest().authenticated();
        http.headers().frameOptions().disable();
        // 认证失败处理类
        http.exceptionHandling().authenticationEntryPoint(new CustAuthenticationEntryPoint());
        // 注销成功处理器
        http.logout().logoutUrl("/logout").logoutSuccessHandler(new CustLogoutSuccessHandler());
    }
}
